<template>
  <div class="home-container" ref="container" v-loading="isLoading">
    <ul
      v-if="data.length"
      class="image-container"
      @transitionend="handleTransitionEnd"
      @wheel="handleWheel"
      :style="{
        transform: `translateY(${top})`,
      }"
    >
      <li
        v-for="(item, i) in data"
        :key="item.id"
        @mouseleave="handleMouseLeave"
        @mousemove="handleMouseMove"
      >
        <div class="image-loader" ref="imageLoader">
          <ImageLoader
            @load="handleLoad(i)"
            :src="item.bigImg"
            :placeholder="item.midImg"
          />
        </div>
        <h1 class="title" ref="title">{{ item.title }}</h1>
        <h2 class="desc" ref="desc">{{ item.description }}</h2>
      </li>
    </ul>
    <ul class="indicator">
      <li
        class="item"
        v-for="(item, i) in data"
        :key="item.id"
        :class="{
          active: index === i,
        }"
        @click="handleClick(i)"
      ></li>
    </ul>
    <div
      class="icon arrowUp"
      v-show="index > 0"
      @click="handleClick(index - 1)"
    >
      <Icon type="arrowUp" />
    </div>
    <div
      class="icon arrowDown"
      v-show="index < data.length - 1"
      @click="handleClick(index + 1)"
    >
      <Icon type="arrowDown" />
    </div>
  </div>
</template>

<script>
import ImageLoader from "../components/ImageLoader.vue";
import Icon from "../components/Icon.vue";

export default {
  components: {
    ImageLoader,
    Icon,
  },
  data() {
    return {
      index: 0,
      clientHeight: 0,
      clientWidth: 0,
      isSwitching: false,
      scale: 1.1,
      extraSize: {
        width: 0,
        height: 0,
      },
    };
  },
  computed: {
    top() {
      return -this.index * this.clientHeight + "px";
    },
    isLoading(){
      return this.$store.state.banner.isLoading;
    },
    data(){
      return this.$store.state.banner.banner;
    }
  },
  created() {
    this.$store.dispatch("banner/fetchData");  
  },
  mounted() {
    window.addEventListener("resize", this.handleResize);
    this.clientWidth = this.$refs.container.clientWidth;
    this.clientHeight = this.$refs.container.clientHeight;
    this.extraSize = {
      width: this.clientWidth * (this.scale - 1),
      height: this.clientHeight * (this.scale - 1),
    };
  },
  destroyed() {
    window.removeEventListener("resize", this.handleResize);
  },
  methods: {
    handleClick(index) {
      this.index = index;
    },
    handleLoad(index) {
      const titleWidth = this.$refs.title[index].clientWidth;
      const descWidth = this.$refs.desc[index].clientWidth;
      this.$refs.title[index].style.width = 0;
      this.$refs.desc[index].style.width = 0;
      this.$refs.title[index].style.transition = "1.5s";
      this.$refs.desc[index].style.transition = "2s";
      this.$refs.title[index].clientWidth;
      this.$refs.desc[index].clientWidth;
      this.$refs.title[index].style.opacity = 1;
      this.$refs.desc[index].style.opacity = 1;
      this.$refs.title[index].style.width = titleWidth + "px";
      this.$refs.desc[index].style.width = descWidth + "px";
    },
    handleResize() {
      this.clientWidth = this.$refs.container.clientWidth;
      this.clientHeight = this.$refs.container.clientHeight;
      this.extraSize = {
        width: this.clientWidth * (this.scale - 1),
        height: this.clientHeight * (this.scale - 1),
      };
    },
    handleWheel(e) {
      if (this.isSwitching || (e.deltaY < 5 && e.deltaY > -5)) {
        return;
      }
      if (e.deltaY < 0 && this.index > 0) {
        this.isSwitching = true;
        this.index--;
      } else if (e.deltaY > 0 && this.index < this.data.length - 1) {
        this.isSwitching = true;
        this.index++;
      }
    },
    handleTransitionEnd(e) {
      if (e.target.tagName !== "UL") {
        return;
      }
      this.isSwitching = false;
    },
    handleMouseMove(e) {
      const center = {
        x: this.clientWidth / 2,
        y: this.clientHeight / 2,
      };
      const x =
        (((e.offsetX - center.x) / (this.clientWidth / 2)) *
          this.extraSize.width) /
        2;
      const y =
        (((e.offsetY - center.y) / (this.clientHeight / 2)) *
          this.extraSize.height) /
        2;
      this.$refs.imageLoader[
        this.index
      ].style.transform = `translate(${-x}px, ${-y}px) scale(${this.scale})`;
    },
    handleMouseLeave() {
      this.$refs.imageLoader[
        this.index
      ].style.transform = `translate(0px, 0px) scale(${this.scale})`;
    },
  },
};
</script>

<style scoped lang="less">
@import "~@/styles/color.less";

@keyframes jump-up {
  0% {
    transform: translateY(-15px);
  }
  50% {
    transform: translateY(15px);
  }
  100% {
    transform: translateY(-15px);
  }
}

@keyframes jump-down {
  0% {
    transform: translateY(15px);
  }
  50% {
    transform: translateY(-15px);
  }
  100% {
    transform: translateY(15px);
  }
}

.home-container {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
  .image-container {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    transform: translateY(0px);
    transition: all 0.5s;
    li {
      width: 100%;
      height: 100%;
      overflow: hidden;
      position: relative;
      color: #fff;
      white-space: nowrap;
      text-shadow: 1px 0 0 rgba(0, 0, 0, 0.5), -1px 0 0 rgba(0, 0, 0, 0.5),
        0 -1px 0 rgba(0, 0, 0, 0.5), 0 1px 0 rgba(0, 0, 0, 0.5);
      .image-loader {
        width: 100%;
        height: 100%;
        position: absolute;
        transition: all 0.2s;
        transform: translate(0px, 0px) scale(1.1);
        z-index: -1;
      }
      .title {
        opacity: 0;
        overflow: hidden;
        position: absolute;
        left: 30px;
        top: 50%;
        transform: translateY(-40px);
      }
      .desc {
        opacity: 0;
        overflow: hidden;
        font-weight: normal;
        position: absolute;
        left: 30px;
        top: 50%;
        transform: translateY(20px);
      }
    }
  }
  .indicator {
    position: absolute;
    width: 20px;
    height: 100px;
    right: 30px;
    top: 50%;
    transform: translateY(-50%);
    .item {
      width: 7px;
      height: 7px;
      background-color: #333;
      cursor: pointer;
      margin-bottom: 10px;
      border: 1px solid #fff;
      box-sizing: border-box;
      transition: 0.5s;
      border-radius: 50%;
      &.active {
        background-color: #fff;
      }
    }
  }
  .icon {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    color: @gray;
    font-size: 25px;
    cursor: pointer;
    &.arrowUp {
      top: 25px;
      animation: jump-up 3s infinite;
    }
    &.arrowDown {
      bottom: 25px;
      animation: jump-down 3s infinite;
    }
  }
}
</style>